package com.lucker.service.caipiaomisscodelist;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.lucker.cds.model.CustomCaiPiaoMissCodeList;
import com.lucker.common.enums.MissTypeSortType;
import com.lucker.common.model.MissCodeList;
import com.lucker.common.model.RedisKey;
import com.lucker.common.util.InitMissNumberUtil;
import com.lucker.common.util.MissCode;
import com.lucker.common.util.MissDataUtil;
import com.lucker.common.util.MissDataUtilNew;
import com.lucker.common.util.StringUtil;
import com.lucker.ds.mapper.BaseCustomMapper;
import com.lucker.ds.model.CaiPiaoMissCodeList;
import com.lucker.ds.model.CaiPiaoMissType;
import com.lucker.framework.constant.ResponseResultModel;
import com.lucker.framework.exception.BaseServiceException;
import com.lucker.service.BaseServiceImpl;
import com.lucker.service.cache.redis.RedisUtil;
import com.lucker.service.caipiaomisstype.CaiPiaoMissTypeService;

@Service
public class CaiPiaoMissCodeListServiceImpl extends BaseServiceImpl<CaiPiaoMissCodeList, CustomCaiPiaoMissCodeList, Long> implements CaiPiaoMissCodeListService {
	
	
	
	@Autowired
	CaiPiaoMissTypeService caiPiaoMissTypeService;
	
	@Autowired
	CaiPiaoMissCodeListService  caiPiaoMissCodeListService;
	

	@Autowired
	RedisUtil redisUtil;
	
	private ExecutorService	executorService	= Executors.newFixedThreadPool(10);
	
	
	@Override
	public BaseCustomMapper<CustomCaiPiaoMissCodeList, Long> getCustomMapper() {
		return null;
	}

	public void initCaiPiaoMissCodeList(Long _caiId) {
		List<Long> skipList = new ArrayList<Long>();
		skipList.add(13L);
		skipList.add(136L);
		skipList.add(14l);
		skipList.add(19l);
		skipList.add(147l);
		skipList.add(15l);
		skipList.add(20L);
		skipList.add(34L);
		skipList.add(21L);
		skipList.add(35L);
		skipList.add(56L);
		skipList.add(36L);
		skipList.add(81L);
		skipList.add(37L);
		skipList.add(111L);
		skipList.add(126L);
		
		CaiPiaoMissType queryParam = new CaiPiaoMissType();
		queryParam.setCaiId(_caiId);
		queryParam.orderById(true);
		List<CaiPiaoMissType> list = caiPiaoMissTypeService.queryAll(queryParam);
		
		for(CaiPiaoMissType cm : list) {
			if(!skipList.contains(cm.getMissTypeId())) {
				continue;
			}
			CaiPiaoMissType _queryParam = new CaiPiaoMissType();
			_queryParam.setMissTypeParentId(cm.getMissTypeId());
			int childRows = caiPiaoMissTypeService.queryAllCount(_queryParam);
			
			List<MissCode> missCodeList = new ArrayList<MissCode>();
			if(childRows < 1) {
		           int missTypeId = cm.getMissTypeId().intValue();
				   switch (missTypeId){
			            case 8://前一直选
			            	missCodeList = InitMissNumberUtil.getPermuteList(11,1);
			                break;
			            case 9://前二直选
			            	missCodeList = InitMissNumberUtil.getPermuteList(11,2);
			                break;
			            case 11://前三直选
			            	missCodeList = InitMissNumberUtil.getPermuteList(11,3);
			                break;
			            case 13://任二单式
			            case 136://前二组选单式
			            	missCodeList = InitMissNumberUtil.getCombinationNumberList(11,2);
			                break;
			            case 14://任二三码
			            case 19://任三单式
			            case 147://前三组选单式
			            	missCodeList = InitMissNumberUtil.getCombinationNumberList(11,3);
			                break;
			            case 15://任二四码
			            case 20://任三四码
			            case 34://任四单式
			            	missCodeList = InitMissNumberUtil.getCombinationNumberList(11,4);
			                break;
			            case 16://任二一胆两拖
			            case 138://前二组选一胆两拖
			            	missCodeList = InitMissNumberUtil.dantuoCombinationNumber(11,1,2);
			                break;
			            case 17://任二一胆三拖
			            case 22://任三一胆三拖
			            case 139://前二组选一胆三拖
			            case 148://前三组选单式一胆三拖
			            	missCodeList = InitMissNumberUtil.dantuoCombinationNumber(11,1,3);
			                break;
			            case 18://任二一胆四拖
			            case 23://任三一胆四拖
			            case 38://任四一胆四拖
			            case 140://前二组选一胆四拖
			            case 149://前三组选一胆四拖
			            	missCodeList = InitMissNumberUtil.dantuoCombinationNumber(11,1,4);
			                break;
			            case 21://任三五码
			            case 35://任四五码
			            case 56://任五单式
			            	missCodeList = InitMissNumberUtil.getCombinationNumberList(11,5);
			                break;
			            case 24://任三一胆五拖
			            case 39://任四一胆五拖
			            case 57://任五一胆五拖
			            case 141://前二组选一胆五拖
			            case 150://前三组选一胆五拖
			            	missCodeList = InitMissNumberUtil.dantuoCombinationNumber(11,1,5);
			                break;
			            case 25://任三二胆二拖
			            case 156://前三组选二胆二拖
			            	missCodeList = InitMissNumberUtil.dantuoCombinationNumber(11,2,2);
			                break;
			            case 26://任三二胆三拖
			            case 42://任四二胆三拖
			            case 157://前三组选二胆三拖
			            	missCodeList = InitMissNumberUtil.dantuoCombinationNumber(11,2,3);
			                break;
			            case 27://任三二胆四拖
			            case 43://任四二胆四拖
			            case 63://任五二胆四拖
			            case 158://前三组选二胆四拖
			            	missCodeList = InitMissNumberUtil.dantuoCombinationNumber(11,2,4);
			                break;
			            case 28://任三二胆五拖
			            case 44://任四二胆五拖
			            case 64://任五二胆五拖
			            case 89://任六二胆五拖
			            case 159://前三组选二胆五拖
			            	missCodeList = InitMissNumberUtil.dantuoCombinationNumber(11,2,5);
			                break;
			            case 29://任三二胆六拖
			            case 45://任四二胆六拖
			            case 65://任五二胆六拖
			            case 90://任六二胆六拖
			            case 114://任七二胆六拖
			            case 160://前三组选二胆六拖
			            	missCodeList = InitMissNumberUtil.dantuoCombinationNumber(11,2,6);
			                break;
			            case 30://任三二胆七拖
			            case 46://任四二胆七拖
			            case 66://任五二胆七拖
			            case 91://任六二胆七拖
			            case 128://任八二胆七拖
			            case 161://前三组选二胆七拖
			            	missCodeList = InitMissNumberUtil.dantuoCombinationNumber(11,2,7);
			                break;
			            case 31://任三二胆八拖
			            case 47://任四二胆八拖
			            case 67://任五二胆八拖
			            case 162://前三组选二胆八拖
			            	missCodeList = InitMissNumberUtil.dantuoCombinationNumber(11,2,8);
			                break;
			            case 32://任三二胆九拖
			            case 48://任四二胆九拖
			            case 68://任五二胆九拖
			            case 163://前三组选二胆九拖
			            	missCodeList = InitMissNumberUtil.dantuoCombinationNumber(11,2,9);
			                break;
			            case 36://任四六码
			            case 81://任六单式
			            	missCodeList = InitMissNumberUtil.getCombinationNumberList(11,6);
			                break;
			            case 37://任四七码
			            case 111://任七单式
			            	missCodeList = InitMissNumberUtil.getCombinationNumberList(11,7);
			                break;
			            case 40://任四一胆六拖
			            case 58://任五一胆六拖
			            case 83://任六一胆六拖
			            case 142://前二组选一胆六拖
			            case 151://前三组选一胆六拖
			            	missCodeList = InitMissNumberUtil.dantuoCombinationNumber(11,1,6);
			                break;
			            case 41://任四一胆七拖
			            case 59://任五一胆七拖
			            case 84://任六一胆七拖
			            case 112://任七一胆七拖
			            case 143://前二组选一胆七拖
			            case 152://前三组选一胆七拖
			            	missCodeList = InitMissNumberUtil.dantuoCombinationNumber(11,1,7);
			                break;
			            case 49://任四三胆二拖
			            	missCodeList = InitMissNumberUtil.dantuoCombinationNumber(11,3,2);
			                break;
			            case 50://任四三胆三拖
			            case 69://任五三胆三拖
			            	missCodeList = InitMissNumberUtil.dantuoCombinationNumber(11,3,3);
			                break;
			            case 51://任四三胆四拖
			            case 70://任五三胆四拖
			            case 95://任六三胆四拖
			            	missCodeList = InitMissNumberUtil.dantuoCombinationNumber(11,3,4);
			                break;
			            case 52://任四三胆五拖
			            case 71://任五三胆五拖
			            case 96://任六三胆五拖
			            case 115://任七三胆五拖
			            	missCodeList = InitMissNumberUtil.dantuoCombinationNumber(11,3,5);
			                break;
			            case 53://任四三胆六拖
			            case 72://任五三胆六拖
			            case 97://任六三胆六拖
			            case 129://任八三胆六拖
			            	missCodeList = InitMissNumberUtil.dantuoCombinationNumber(11,3,6);
			                break;
			            case 54://任四三胆七拖
			            case 73://任五三胆七拖
			            case 98://任六三胆七拖
			            	missCodeList = InitMissNumberUtil.dantuoCombinationNumber(11,3,7);
			                break;
			            case 55://任四三胆八拖
			            case 74://任五三胆八拖
			            case 99://任六三胆八拖
			            	missCodeList = InitMissNumberUtil.dantuoCombinationNumber(11,3,8);
			                break;
			            case 60://任五一胆八拖
			            case 113://任七一胆八拖
			            case 127://任八一胆八拖
			            case 144://前二组选一胆八拖
			            case 153://前三组选一胆八拖
			            	missCodeList = InitMissNumberUtil.dantuoCombinationNumber(11,1,8);
			                break;
			            case 61://任五一胆九拖
			            case 145://前二组选一胆九拖
			            case 154://前三组选一胆九拖
			            	missCodeList = InitMissNumberUtil.dantuoCombinationNumber(11,1,9);
			                break;
			            case 62://任五一胆十拖
			            case 146://前二组选一胆十拖
			            case 155://前三组选一胆十拖
			            	missCodeList = InitMissNumberUtil.dantuoCombinationNumber(11,1,10);
			                break;
			            case 75://任五四胆二拖
			            	missCodeList = InitMissNumberUtil.dantuoCombinationNumber(11,4,2);
			                break;
			            case 76://任五四胆三拖
			            case 101://任六四胆三拖
			            	missCodeList = InitMissNumberUtil.dantuoCombinationNumber(11,4,3);
			                break;
			            case 77://任五四胆四拖
			            case 102://任六四胆四拖
			            case 116://任七四胆四拖
			            	missCodeList = InitMissNumberUtil.dantuoCombinationNumber(11,4,4);
			                break;
			            case 78://任五四胆五拖
			            case 103://任六四胆五拖
			            case 117://任七四胆五拖
			            case 130://任八四胆五拖
			            	missCodeList = InitMissNumberUtil.dantuoCombinationNumber(11,4,5);
			                break;
			            case 79://任五四胆六拖
			            case 104://任六四胆六拖
			            	missCodeList = InitMissNumberUtil.dantuoCombinationNumber(11,4,6);
			                break;
			            case 80://任五四胆七拖
			            case 105://任六四胆七拖
			            	missCodeList = InitMissNumberUtil.dantuoCombinationNumber(11,4,7);
			                break;
			            case 106://任六五胆二拖
			            	missCodeList = InitMissNumberUtil.dantuoCombinationNumber(11,5,2);
			                break;
			            case 107://任六五胆三拖
			            case 118://任七五胆三拖
			            	missCodeList = InitMissNumberUtil.dantuoCombinationNumber(11,5,3);
			                break;
			            case 108://任六五胆四拖
			            case 119://任七五胆四拖
			            case 131://任八五胆四拖
			            	missCodeList = InitMissNumberUtil.dantuoCombinationNumber(11,5,4);
			                break;
			            case 109://任六五胆五拖
			            case 120://任七五胆五拖
			            	missCodeList = InitMissNumberUtil.dantuoCombinationNumber(11,5,5);
			                break;
			            case 110://任六五胆六拖
			            case 121://任七五胆六拖
			            	missCodeList = InitMissNumberUtil.dantuoCombinationNumber(11,5,6);
			                break;
			            case 122://任七六胆二拖
			            	missCodeList = InitMissNumberUtil.dantuoCombinationNumber(11,6,2);
			                break;
			            case 123://任七六胆三拖
			            case 132://任八六胆三拖
			            	missCodeList = InitMissNumberUtil.dantuoCombinationNumber(11,6,3);
			                break;
			            case 124://任七六胆四拖
			            	missCodeList = InitMissNumberUtil.dantuoCombinationNumber(11,6,4);
			                break;
			            case 125://任七六胆五拖
			            	missCodeList = InitMissNumberUtil.dantuoCombinationNumber(11,6,5);
			                break;
			            case 126://任八单式
			            	missCodeList = InitMissNumberUtil.getCombinationNumberList(11,8);
			                break;
			            case 133://任八七胆二拖
			            	missCodeList = InitMissNumberUtil.dantuoCombinationNumber(11,7,2);
			                break;
			            case 134://任八七胆三拖
			            	missCodeList = InitMissNumberUtil.dantuoCombinationNumber(11,7,3);
			                break;
			            case 135://任八七胆四拖
			            	missCodeList = InitMissNumberUtil.dantuoCombinationNumber(11,7,4);
			                break;
			        }
				   if(cm.getMissTypeId() == 13L) {
						getLOGGER().error("==============================================>bbbbb 13 : " + childRows);
				   }
				   
				   //写入COODE表
				   CaiPiaoMissCodeList cmcl = null ;
				   
				   for(MissCode mc : missCodeList) {
					   cmcl = new CaiPiaoMissCodeList();
					   List<Integer> firstNumberList  = mc.getFirstCode();
					   List<Integer> secondNumberList = mc.getSecondCode();
					   List<Integer> thirdNumberList  = mc.getThirdCode();
					   
					   cmcl.setCaiId(cm.getCaiId());
					   cmcl.setMissTypeId(cm.getMissTypeId());
					   cmcl.setMissTypeName(cm.getMissTypeName());
					   if(CollectionUtils.isNotEmpty(firstNumberList)) {
						     String _code = StringUtils.join(firstNumberList, ",");
					         cmcl.setFirstNum(_code);
					   }
					   if(CollectionUtils.isNotEmpty(secondNumberList)) {
						   String _code = StringUtils.join(secondNumberList, ",");
					       cmcl.setSecondNum(_code);
					   }
					   if(CollectionUtils.isNotEmpty(thirdNumberList)) {
						   String _code = StringUtils.join(thirdNumberList, ",");
					         cmcl.setThirdNum(_code);
					   }
					   cmcl.setCaiTypeId(cm.getCaiTypeId());
					   cmcl.setCurrentMissValue(0);
					   cmcl.setAppearProbability(BigDecimal.ZERO);
					   cmcl.setReplenishProbability(BigDecimal.ZERO);
					   cmcl.setTeenMissValue(0);
					   cmcl.setMaxMissValue(0);
					   add(cmcl, false);
				   }
	         }
		}
		
	}
	
	public ResponseEntity<?> missCodeList(Long _caiId,Long missTypeId){
		
		String key = RedisKey.MISSTYPE_CODE_REDIS_KEY + _caiId;
		String misscodestr = redisUtil.hmget(key, String.valueOf(missTypeId));
		String codeRowDatas[] = misscodestr.split(",");
		JSONObject obj = null;
		String lastIssueNo = redisUtil.get(RedisKey.MISSTYPE_CODE_LAST_ISSUENO_REDIS_KEY + _caiId);
		
		Map<String,Object> retMapObject = new HashMap<String,Object>();
		List<JSONObject> jsonList = new ArrayList<JSONObject>();
		
		for(String codestr : codeRowDatas) {
			obj = new JSONObject();
			String codes_fileds[] = codestr.split("\\|");
			obj.put("id", codes_fileds[0]);
			obj.put("missTypeId", codes_fileds[1]);
			obj.put("firstNum", codes_fileds[2]);
			obj.put("secondNum", codes_fileds[3]);
			obj.put("currentMissValue", codes_fileds[4]);
			obj.put("appearProbability", "");
			obj.put("replenishProbability", "");
			obj.put("teenMissValue", codes_fileds[5]);
			obj.put("maxMissValue", codes_fileds[6]);
			//temp = id + "|" + missTypeId + "|" + fristnum + "|" +   secondnum + "|" + current_miss_value + "|" + teenMissValue + "|" + maxMissValue;
			
			List<Integer> fristNumberList = new ArrayList<Integer>();
			List<Integer> secondNumberList = new ArrayList<Integer>();
			if(StringUtil.isNotBlank(codes_fileds[2])) {
				fristNumberList = StringUtil.stringToListInteger(codes_fileds[2], "*");
			}
			if(StringUtil.isNotBlank(codes_fileds[3])) {
				secondNumberList = StringUtil.stringToListInteger(codes_fileds[3], "*");
			}
			
			obj.put("fristNumberList", fristNumberList);
			obj.put("secondNumberList", secondNumberList);
			jsonList.add(obj);
		}
		retMapObject.put("list", jsonList);
		retMapObject.put("lastIssueNo", lastIssueNo);
		return new ResponseEntity<>(new ResponseResultModel<Map<String,Object>>(retMapObject),HttpStatus.OK);
	}

	
	public ResponseEntity<?> missCodeList(Long _caiId,Long missTypeId , int pageSize,int pageIndex, String sortType){
		
		CaiPiaoMissCodeList query = new CaiPiaoMissCodeList();
		query.setCaiId(_caiId);
		query.setMissTypeId(missTypeId);
		if(StringUtils.equals(MissTypeSortType.A1.getCode(), sortType)) {
			query.orderByCurrentMissValue(true);
		}
		if(StringUtils.equals(MissTypeSortType.A2.getCode(), sortType)) {
			query.orderByCurrentMissValue(false);		
		}
		if(StringUtils.equals(MissTypeSortType.B1.getCode(), sortType)) {
			query.orderByAppearProbability(true);
		}
		if(StringUtils.equals(MissTypeSortType.B2.getCode(), sortType)) {
			query.orderByAppearProbability(false);
		}
		if(StringUtils.equals(MissTypeSortType.A3.getCode(), sortType)) {
			query.orderByReplenishProbability(true);
		}
		if(StringUtils.equals(MissTypeSortType.B3.getCode(), sortType)) {
			query.orderByReplenishProbability(false);
		}
		if(StringUtils.equals(MissTypeSortType.A4.getCode(), sortType)) {
			query.orderByMaxMissValue(true);
		}
		if(StringUtils.equals(MissTypeSortType.B4.getCode(), sortType)) {
			query.orderByMaxMissValue(false);
		}
		
		PageHelper.startPage(pageIndex, pageSize);
		List<CaiPiaoMissCodeList> list = queryAll(query);
		@SuppressWarnings({ "rawtypes", "unchecked" })
		PageInfo page = new PageInfo(list);
		Map<String,Object> retMapObject = new HashMap<String,Object>();
		List<JSONObject> jsonList = new ArrayList<JSONObject>();
		for(CaiPiaoMissCodeList ccl : list) {
			JSONObject obj = JSONObject.parseObject(JSONObject.toJSONString(ccl));
			List<Integer> fristNumberList = new ArrayList<Integer>();
			List<Integer> secondNumberList = new ArrayList<Integer>();
			List<Integer> thirdNumberList = new ArrayList<Integer>();
			if(StringUtil.isNotBlank(ccl.getFirstNum())) {
				fristNumberList = StringUtil.stringToListInteger(ccl.getFirstNum(), ",");
			}
			if(StringUtil.isNotBlank(ccl.getSecondNum())) {
				secondNumberList = StringUtil.stringToListInteger(ccl.getSecondNum(), ",");
			}
			if(StringUtil.isNotBlank(ccl.getThirdNum())) {
				thirdNumberList = StringUtil.stringToListInteger(ccl.getThirdNum(), ",");
			}
			obj.put("fristNumberList", fristNumberList);
			obj.put("secondNumberList", secondNumberList);
			obj.put("thirdNumberList", thirdNumberList);
			jsonList.add(obj);
		}
		
		retMapObject.put("list", jsonList);
		
		
		
		return new ResponseEntity<>(new ResponseResultModel<Map<String,Object>>(retMapObject),HttpStatus.OK);
	}
	

	public ResponseEntity<?> matchingMissCode(Long _caiId,String openCode,String issueNo){
		int pageIndex = 1;
		int pageSize  = 1000;
		//check param
		getLOGGER().error("开始匹配遗漏号码........................." + issueNo + "----" + issueNo);
		if(StringUtil.isBlank(openCode)) {
			throw new BaseServiceException("匹配遗漏号码错误，参数 opencode 不能为空");
		}
		if(StringUtil.isBlank(issueNo)) {
			throw new BaseServiceException("匹配遗漏号码错误，参数 issueNo 不能为空");
		}
		
		//STEP  1
		CaiPiaoMissCodeList queryCaiPiaoMissCodeList = new CaiPiaoMissCodeList();
		queryCaiPiaoMissCodeList.setCaiId(Long.valueOf(_caiId));
		
		PageHelper.startPage(pageIndex, pageSize);
		List<CaiPiaoMissCodeList> list = queryAll(queryCaiPiaoMissCodeList);
		while(CollectionUtils.isNotEmpty(list)) {
			ArrayList<Integer> firstNums;
			ArrayList<Integer> secondNums;
			ArrayList<Integer> awardNums;
			for(CaiPiaoMissCodeList cpcode : list) {
				
				firstNums = null;
				secondNums = null;
				awardNums  = null;
				
				Long missTypeId = cpcode.getMissTypeId();
				String fristNumberString = cpcode.getFirstNum();
				String secondNumberString = cpcode.getSecondNum();
				
				if(StringUtil.isNotBlank(fristNumberString)) {
					firstNums = StringUtil.stringToArrayListInteger(fristNumberString, ",");
				}
				if(StringUtil.isNotBlank(secondNumberString)) {
					secondNums = StringUtil.stringToArrayListInteger(secondNumberString, ",");
				}
				awardNums = StringUtil.stringToArrayListInteger(openCode, ",");
				
				int newMissValue = MissDataUtil.calculateCurrentMissValue(missTypeId.intValue(), firstNums, secondNums, awardNums, cpcode.getCurrentMissValue());
				
				cpcode.setCurrentMissValue(newMissValue);
				cpcode.setLastIssueNo(issueNo);
				modify(cpcode, false);
				
			}
			
			pageIndex++;
			PageHelper.startPage(pageIndex, pageSize);
			list = queryAll(queryCaiPiaoMissCodeList);
		}
		
		
		return null;
	}
	
	
	
	
	
	
	public void initMissCodeToRedis(Long _caiId){
//		int pageIndex = 1;
//		int pageSize  = 10000;
//		
//		CaiPiaoMissCodeList queryCaiPiaoMissCodeList = new CaiPiaoMissCodeList();
//		queryCaiPiaoMissCodeList.orderById(true);
//		PageHelper.startPage(pageIndex, pageIndex);
//		Long begin = new Date().getTime();
//		List<CaiPiaoMissCodeList> list = queryAll(queryCaiPiaoMissCodeList);
//		
//		@SuppressWarnings("unused")
//		String fix = "set";
//		while(CollectionUtils.isNotEmpty(list)) {
//			String setvalue;
//			for(CaiPiaoMissCodeList cpcode : list) {
//				setvalue = "";
//				String frist =  cpcode.getFirstNum() == null ? "" : cpcode.getFirstNum();
//				String second = cpcode.getSecondNum() == null ? "" : cpcode.getSecondNum();
//				setvalue = cpcode.getCaiId() + "|" + cpcode.getId() + "|" + cpcode.getMissTypeId() + "|" + frist + "|" + second; 
//				redisUtil.sadd(fix+":misscode:" + cpcode.getCaiId(), setvalue);
//			}
//			
//			pageIndex++;
//			PageHelper.startPage(pageIndex, pageSize);
//			list = queryAll(queryCaiPiaoMissCodeList);
//		}
		
		Map<String,String> map = new HashMap<String,String>();
		CaiPiaoMissType queryCaiPiaoMissType = new CaiPiaoMissType();
		queryCaiPiaoMissType.setCaiId(_caiId);
		List<CaiPiaoMissType> list = caiPiaoMissTypeService.queryAll(queryCaiPiaoMissType);
		
		for(CaiPiaoMissType cpmt : list) {
			Long missTypeId = cpmt.getMissTypeId();
			CaiPiaoMissCodeList queryCaiPiaoMissCodeList = new CaiPiaoMissCodeList();
			queryCaiPiaoMissCodeList.setCaiId(_caiId);
			queryCaiPiaoMissCodeList.setMissTypeId(missTypeId);
			List<CaiPiaoMissCodeList> innerList = caiPiaoMissCodeListService.queryAll(queryCaiPiaoMissCodeList);
			String missTypeStr = getString(innerList);
			if(CollectionUtils.isNotEmpty(innerList)) {
				map.put(String.valueOf(missTypeId), missTypeStr);
			}else {
				continue;
			}
		}
		
		getLOGGER().error("开始写入REDIS MAP大小:" + map.size() );
		Long begin = new Date().getTime();
		redisUtil.hmset(RedisKey.MISSTYPE_CODE_REDIS_KEY + _caiId , map);
		Long step1 = new Date().getTime();
		getLOGGER().error("完成彩种: "+_caiId+" 写入REDIS时间......................... : " + (step1 - begin) + " 毫秒" );
	}
	
	public void initMissCodeToSystemRam(){
		int cids[] = {101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,201,202,203,123,124};
		//int cids[] = {101};
		Long begin = new Date().getTime();
		for(int cid : cids) {
			//initMissCodeToSystemRam(Long.valueOf(cid));
			initMissCodeToRedis(Long.valueOf(cid));
		}
		
        String val = "初始化系统MAP用时: " + ( (new Date().getTime() - begin ) / 1000) + "秒";
		getLOGGER().error(val);
	}
	public void initMissCodeToSystemRam(Long cid){
		MissCodeList.caiMap = new HashMap<String,List<String>>();
		int pageIndex = 1;
		int pageSize  = 10000;
		//STEP  1
		CaiPiaoMissCodeList queryCaiPiaoMissCodeList = new CaiPiaoMissCodeList();
		queryCaiPiaoMissCodeList.setCaiId(cid);
		queryCaiPiaoMissCodeList.orderById(true);
		PageHelper.startPage(pageIndex, pageIndex);
		
		List<CaiPiaoMissCodeList> list = queryAll(queryCaiPiaoMissCodeList);
		List<String> codelist = new ArrayList<String>();
		
		while(CollectionUtils.isNotEmpty(list)) {
			String setvalue = "";
			for(CaiPiaoMissCodeList cpcode : list) {
				setvalue = "";
				String frist =  cpcode.getFirstNum() == null ? "" : cpcode.getFirstNum();
				String second = cpcode.getSecondNum() == null ? "" : cpcode.getSecondNum();
				setvalue = cpcode.getCaiId() + "|" + cpcode.getId() + "|" + cpcode.getMissTypeId() + "|" + frist + "|" + second;
				codelist.add(setvalue);
			}
			
			pageIndex++;
			PageHelper.startPage(pageIndex, pageSize);
			list = queryAll(queryCaiPiaoMissCodeList);
			getLOGGER().error("条理了10000条记录 : " + cid);
			
		}
		MissCodeList.caiMap.put("cid" + cid, codelist);
	}
	
	public ResponseEntity<?> computeOpenCodeMissValue(String _caiId,String opencode,String issueno){
		//-----------------------------------------------------------------------------------------------------------//
		Set<String> keysArray = redisUtil.hkeys(RedisKey.MISSTYPE_CODE_REDIS_KEY + _caiId);
		if(CollectionUtils.isNotEmpty(keysArray)) {
			Set<Integer> openCodeArray = StringUtil.stringToArraySetInteger(opencode, ",");
			String[] keys = keysArray.toArray(new String[keysArray.size()]);;
			getLOGGER().error("开始读取REDIS");
			Long time1 = new Date().getTime();
			List<String> strList = redisUtil.hmget(RedisKey.MISSTYPE_CODE_REDIS_KEY + _caiId, keys);
			Long time2 = new Date().getTime();
			getLOGGER().error("读取REDIS完成, 用时: " + (time2 - time1) + " 毫秒");
			getLOGGER().error("开始循环计算");
			String[] rowInfo;
			StringBuilder temp = null;
			String missId = null;
			int cai_id_max_value = 0; //用于计算当前CAI_ID 下面的最大遗漏值，计算当前CAI_ID的状态（高，极高）
			Map<String,String> map = new HashMap<String,String>();
			for(String s : strList) {
				//S 为每一个玩法下面的所有号码的字符串累加，用,分割开
				String missTypeStr[] = s.split(",");
				missId = "";
				temp = new StringBuilder();
				String str;
				String innerText = null;
				int missTypeMaxValue = 0;//当前玩法的最大遗漏值，用于计算当前CAIID,当前玩法 的状态（高，极高）
				String _missTypeId = "";
				for(int t = 0 ;  missTypeStr != null && t < missTypeStr.length ; t++) {
					str = missTypeStr[t];
					rowInfo = str.split("\\|");
					if(rowInfo == null || rowInfo.length != 7) {
						continue;
					}
	                String id = rowInfo[0];
	                String missTypeId = rowInfo[1];
	                String fristNum = rowInfo[2];
	                String secondNum = rowInfo[3];
	                String current_miss_value = rowInfo[4] == null ? "0" : rowInfo[4];
	                String teenMissValue = rowInfo[5];
	                String maxMissValue = rowInfo[6] == null ? "0" : rowInfo[6];
	                maxMissValue = "" + (Integer.parseInt(maxMissValue) + 1);
	                //int newMissValue = MissDataUtil.calculateCurrentMissValue(Integer.parseInt(missTypeId), StringUtil.stringToArrayListInteger(fristNum, "*"), StringUtil.stringToArrayListInteger(secondNum, "*"), openCodeArray , Integer.parseInt(current_miss_value));
	                boolean isBinGo = MissDataUtil.isNumsBingGo(Integer.parseInt(missTypeId), StringUtil.stringToArrayListInteger(fristNum, "*"), StringUtil.stringToArrayListInteger(secondNum, "*"), StringUtil.stringToArrayListInteger(opencode, ","));
	                //boolean isBinGo = MissDataUtilNew.isNumsBingGo(Integer.parseInt(missTypeId), StringUtil.stringToArraySetInteger(fristNum, "*"), StringUtil.stringToArraySetInteger(secondNum, "*"), openCodeArray);
	                int newMissValue = Integer.parseInt(current_miss_value);
	                
	                if(isBinGo) {//该号码中奖
	                	//更新近10次遗漏，
	                	teenMissValue = updateTeenMissValue(teenMissValue,newMissValue);
	                	//更新最大遗漏
	                	if(Integer.parseInt(maxMissValue) < newMissValue) {
	                		maxMissValue = current_miss_value;
	                	}
	                	//中奖，遗漏值归0
	                	newMissValue = 0;
	                }else {
	                	newMissValue++;
	                }
	                innerText = id + "|" + missTypeId + "|" + fristNum + "|" +   secondNum + "|" + newMissValue + "|" + teenMissValue + "|" + maxMissValue;
	                if(t == (missTypeStr.length - 1)) {
	                	temp.append(innerText);
	                	missId = rowInfo[1];
	                	_missTypeId = missTypeId;
	                }else {
	                	temp.append(innerText).append(",");
	                }
	                
	                //
	                if(newMissValue > missTypeMaxValue) {
	                	missTypeMaxValue = newMissValue;
	                }
				}
				
				//记录当前CAI_ID,当前玩法的最大遗漏值
				final String final_missTypeId = _missTypeId;
				final String final_missTypeMaxValue = String.valueOf(missTypeMaxValue);
				executorService.execute(new Runnable() {
					@Override
					public void run() {
						try {
							String redisMissTypeMaxValueKey = "MISS_MAXVALUE" + ":" + _caiId + ":" + final_missTypeId; 
							redisUtil.set(redisMissTypeMaxValueKey, final_missTypeMaxValue);
						} catch (Exception e) {
							getLOGGER().error("写入REDIS最新遗漏计算期号错误, 详情: {} " , e.getMessage() , e );
						}
					}
				});
				
				//
				if(missTypeMaxValue > cai_id_max_value) {
					cai_id_max_value = missTypeMaxValue;
				}
				map.put(missId, temp.toString());
			}
			
			//异步写入当前CAI_ID下面所有号码的最大遗漏值。
			final String final_cai_id_max_value = String.valueOf(cai_id_max_value);
			executorService.execute(new Runnable() {
				@Override
				public void run() {
					try {
						String redisMissTypeMaxValueKey = "MISS_MAXVALUE" + ":" + _caiId ; 
						redisUtil.set(redisMissTypeMaxValueKey, final_cai_id_max_value);
					} catch (Exception e) {
						getLOGGER().error("写入REDIS最新遗漏计算期号错误, 详情: {} " , e.getMessage() , e );
					}
				}
			});
			
			Long time3 = new Date().getTime();
			getLOGGER().error("计算完成，用时 " + (time3 - time2) + " 毫秒");
			getLOGGER().error("开始更新REDIS" + map.size());
			Long time4 = new Date().getTime();
			redisUtil.hmset(RedisKey.MISSTYPE_CODE_REDIS_KEY + _caiId, map);
			getLOGGER().error("更新REDIS完成.。。。。。用时 : " + (time4 - time3) + " 毫秒");
		}
		
		
		executorService.execute(new Runnable() {
			@Override
			public void run() {
				try {
					redisUtil.set(RedisKey.MISSTYPE_CODE_LAST_ISSUENO_REDIS_KEY + _caiId, issueno);
				} catch (Exception e) {
					getLOGGER().error("写入REDIS最新遗漏计算期号错误, 详情: {} " , e.getMessage() , e );
				}
			}
		});
		
		
		
		
		
		return new ResponseEntity<>(new ResponseResultModel<String>("ok"),HttpStatus.OK);
	}
	
	public String updateTeenMissValue(String missString , int currentMissValue) {
		if(StringUtil.isBlank(missString)) {
			return String.valueOf(currentMissValue);
		}else {
			return missString + "," + currentMissValue;
		}
	}
	
	public ResponseEntity<?> testRedis(){
		Long beg = new Date().getTime();
		for(int i = 0 ; i < 500000 ; i++) {
			redisUtil.set("tts:" + "ids" + i , "val" + i);
		}
		String val = "SET 500000个 REDIS 字符串用时: " + ( (new Date().getTime() - beg ) / 1000) + "秒";
		getLOGGER().error(val);
		return new ResponseEntity<>(new ResponseResultModel<String>(val),HttpStatus.OK);
	}
	
	
	
	
	
	
	
	
	public void writeRedis(Long cai_id) {
		Map<String,String> testMap = new HashMap<>();
		Long sbeg = new Date().getTime();
		for(int i = 0 ; i < 160 ; i++) {
			List<String> innerList = new ArrayList<String>();
			for(int t = 0  ; t < 4000 ; t++) {
				innerList.add(String.valueOf(t));
			}
			testMap.put("mapkey" + i, JSONObject.toJSONString(innerList));
		}
		getLOGGER().error(" 160 -- 4000 循环耗时  。。。。。: " + (new Date().getTime() - sbeg) + "  毫秒");
		
		Long beg = new Date().getTime();
		redisUtil.hmset("tests:misstypeId:9999", testMap);
		getLOGGER().error(" 写入耗时  。。。。。: " + (new Date().getTime() - sbeg) + "  毫秒   条数 : " + (160 * 4000) );	
		
	}

	public void readRedis(Long cai_id) {
		String keys = "misscode:" + cai_id + ":*";
		Long leiji = 0l;
		Set<String> sets = redisUtil.getKeys(keys);
		for(String key : sets) {
			Long begin  = new Date().getTime();
			String str_value = redisUtil.get(key);
			Long subTime = new Date().getTime() - begin ;
			leiji = leiji + subTime;
			getLOGGER().error("获取 玩法ID : " + key + "   用时 : " + subTime + "毫秒 ! ");
		}
		getLOGGER().error("取当前彩种 :" + cai_id  + "  从REDIS 读取累计用时: " + leiji + "毫秒");
	}
	
	
	
	
	
	public List<String> getStringList(List<CaiPiaoMissCodeList> clist){
		String temp = null;
		List<String> strList = new ArrayList<String>();
		for(CaiPiaoMissCodeList c : clist) {
			temp = "";
			Long id = c.getId();
			Long cai_id = c.getCaiId();
			Long missTypeId = c.getMissTypeId();
			String fristnum = c.getFirstNum();
			String secondnum = c.getSecondNum();
			int current_miss_value = c.getCurrentMissValue();
			String teenMissValue  = String.valueOf(c.getTeenMissValue());
			int maxMissValue = c.getMaxMissValue();
			//temp = id + "|" + cai_id + "|" + missTypeId + "|" + fristnum + "|" +   secondnum + "|" + current_miss_value + "|" + teenMissValue + "|" + maxMissValue;
			if(StringUtil.isNotBlank(fristnum)) {
				fristnum = fristnum.replaceAll(",", "*");
			}
			if(StringUtil.isNotBlank(secondnum)) {
				secondnum = secondnum.replaceAll(",", "*");
			}
			temp = id + "|" + missTypeId + "|" + fristnum + "|" +   secondnum + "|" + current_miss_value + "|" + teenMissValue + "|" + maxMissValue;
			
			strList.add(temp);
			
		}
		return strList;
	}
	
	
	
	
	public String getString(List<CaiPiaoMissCodeList> clist){
		String temp = "";
		for(int i = 0 ; clist != null && i < clist.size() ; i++) {
			CaiPiaoMissCodeList c = clist.get(i);
			Long id = c.getId();
			Long missTypeId = c.getMissTypeId();
			String fristnum = c.getFirstNum() == null ? "" : c.getFirstNum() ;
			String secondnum = c.getSecondNum() == null ? "" : c.getSecondNum() ;
			int current_miss_value = c.getCurrentMissValue();
			String teenMissValue  = String.valueOf(c.getTeenMissValue());
			int maxMissValue = c.getMaxMissValue();
			if(StringUtil.isNotBlank(fristnum)) {
				fristnum = fristnum.replaceAll(",", "*");
			}
			if(StringUtil.isNotBlank(secondnum)) {
				secondnum = secondnum.replaceAll(",", "*");
			}
			
			if(i == (clist.size() - 1)) {
				temp = temp + id + "|" + missTypeId + "|" + fristnum + "|" +   secondnum + "|" + current_miss_value + "|" + teenMissValue + "|" + maxMissValue  ;
			}else {
				temp = temp + id + "|" + missTypeId + "|" + fristnum + "|" +   secondnum + "|" + current_miss_value + "|" + teenMissValue + "|" + maxMissValue + "," ;
			}
		}
		
		return temp;
	}
	
	
}
